#ifndef __MUL_TASK_H__
#define __MUL_TASK_H__

#include "stdint.h"


typedef void (*TaskCallBackFunc)(void * p_context);
typedef struct _Task * TaskPtr;
typedef struct _Task
{
    uint16_t    tick;   //计数变量
    uint16_t    limit;  //时间上限
    uint8_t     flag;   //时间到期标志位
    TaskPtr      p_next_task; //下一个task的指针
    TaskCallBackFunc cb;     //对应的回调函数
    void * p_context;   //用于保存回调函数的参数
} Task;
 
typedef enum
{
    TASK_ERR_OK = 0x00, //正常
    TASK_ERR_NULL_TASK, //任务为空
    TASK_ERR_NULL_CB, //回调函数为空
    TASK_ERR_LIMIT, //limit为0
    TASK_ERR_TICK,  //设置的tick错误
    TASK_ERR_NO_INIT_MULTASK, //未初始化多任务模块
}TaskErrCode; //MulTask返回的错误码


/**
* @brief : TaskErrCode MulTask_Init(Task* p_idle_task,TaskCallBackFunc idle_cb ,void * p_context);
* @param : p_idle_task 任务结构体指针
* @param : idle_cb 空闲任务回调函数
* @param : p_context 空闲任务回调函数的参数
* @attention : MulTask模块必须调用的初始化函数
* @author : Sheep
* @date : 24/08/22
*/
TaskErrCode MulTask_Init(Task* p_idle_task,TaskCallBackFunc idle_cb ,void * p_context);
/**
* @brief : TaskErrCode MulTask_TaskInit(Task* p_task, uint16_t sep_tick, TaskCallBackFunc cb, void * p_context);
* @param : p_task 任务结构体指针
* @param : sep_tick 任务间隔时间(单位 tick,MulTask_Tick()函数的调用周期)
* @param : cb 回调函数
* @param : p_context 回调函数的参数
* @attention : None
* @author : Sheep
* @date : 24/08/22
*/
TaskErrCode MulTask_TaskInit(Task* p_task, uint16_t sep_tick, TaskCallBackFunc cb, void * p_context);
/**
* @brief : TaskErrCode MulTask_Tick(void);
* @param : None
* @attention : MulTask_Tick()函数为每个任务做定时tick的检查
* @author : Sheep
* @date : 24/08/22
*/
TaskErrCode MulTask_Tick(void);
/**
* @brief : TaskErrCode MulTask_Loop(void);
* @param : None
* @attention : MulTask_Loop()函数为MulTask模块中各个任务回调函数统一执行的函数，建议在主循环中直接调用
* @attention ：同时提供了另外一种方式，可以给调用者单独判断执行Task的能力，不需要借用回调函数(即MulTask_CheckTask和MulTask_ResetTask)
* @author : Sheep
* @date : 24/08/22
*/
TaskErrCode MulTask_Loop(void);

#define MulTask_CheckTask(p_task) ((p_task)->flag)
#define MulTask_ResetTask(p_task) ((p_task)->flag = false)

/**
* @brief : TaskErrCode MulTask_SetTaskStartTick(Task * p_task, uint16_t tick);
* @param : p_task, Task * 要设置的task
* @param : tick, uint16_t 对应task的初始tick，不设置的话默认为0；
* @attention : 这个函数是用于在一定程度上错开task运行的时间，如：
                taskA 10ms，taskB 1s,那每1000ms两个task就会在同时触发运行，这样这一时刻task_loop的时间就会比较长
                如果初始task将taskA设置为5,这种情况在taskA运行时间不超过5ms时，
                可以保证两个task一直错开，更好利于MulTask的运行。
                当然不设置的话也不会有任何问题。
* @author : Sheep
* @date : 24/08/22
*/
TaskErrCode MulTask_SetTaskStartTick(Task * p_task, uint16_t tick);

#endif
